package com.ronghui.cash.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ronghui.cash.entity.*;
import com.ronghui.cash.parambean.LimuServicePassword;
import com.ronghui.cash.parambean.LimuTokenAndBizType;
import com.ronghui.cash.service.AuthService;
import com.ronghui.cash.service.LimuService;
import com.ronghui.cash.service.UserService;
import com.ronghui.cash.util.CodecUtil;
import com.ronghui.cash.util.ConstUtil;
import com.ronghui.cash.util.DateUtil;
import com.ronghui.cash.util.Util;
import com.ronghui.cash.util.limu.LimuUtil;
import com.ronghui.cash.util.limu.common.HttpClient;
import com.ronghui.cash.util.limu.common.StringUtils;
import com.ronghui.cash.vo.Response;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("auth")
public class AuthLimuController extends BaseController {

    @Autowired
    LimuService limuService;

    @Autowired
    AuthService authService;

    @Autowired
    UserService userService;

    @Value("${limu.apikey}")
    private String limuApikey;

    @Value("${limu.version}")
    private String limuVersion;

    @Value("${limu.apiSecret}")
    private String limuApiSecret;

    @Value("${limu.apiUrl}")
    private String limuApiUrl;

    public static HttpClient httpClient = new HttpClient();


    /**
     * 提交受理请求
     *
     * @param reqParam
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    private Object doPost(List<BasicNameValuePair> reqParam) throws JsonParseException, JsonMappingException, IOException {
        List<BasicNameValuePair> baseParam = new ArrayList<BasicNameValuePair>();
        baseParam.addAll(reqParam);
        baseParam.add(new BasicNameValuePair("apiKey", limuApikey));// API授权
        baseParam.add(new BasicNameValuePair("callBackUrl", ""));// callBackUrl
        baseParam.add(new BasicNameValuePair("version", limuVersion));// 调用的接口版本，
        baseParam.add(new BasicNameValuePair("sign", LimuUtil.signConvert(LimuUtil.strSplitJoint(baseParam), limuApiSecret)));// 请求参数签名

        super.logger.info("userId:" + super.getUserId() + ", 立木的提交受理请求值:" + JSON.toJSONString(baseParam));
        String json = httpClient.doPost(limuApiUrl, baseParam);
        super.logger.info("userId:" + super.getUserId() + ", 立木的提交受理返回值:" + json);

		/*if (StringUtils.isBlank(json)) {
			super.logger.error("立木的受理返回值为空！");
			return "failure";
		}*/

/*		ObjectMapper objectMapper = new ObjectMapper();
		JsonNode rootNode = objectMapper.readValue(json, JsonNode.class);
		String code = rootNode.get("code").textValue();

		if (!"0010".equals(code)) {// 受理失败
			super.logger.error("立木受理失败（code不是0010）,原因："+json);
			return "failure";
		}*/

        return JSON.parseObject(json);
    }

    /**
     * 查询状态
     *
     * @throws Exception
     */

    @RequestMapping("limuStatus")
    public Response limuStatus(@Validated LimuTokenAndBizType lt, HttpServletRequest request) throws Exception {

        List<BasicNameValuePair> reqParam = new ArrayList<BasicNameValuePair>();
        reqParam.add(new BasicNameValuePair("method", "api.common.getStatus"));// 接口名称
        reqParam.add(new BasicNameValuePair("apiKey", limuApikey));// API授权
        reqParam.add(new BasicNameValuePair("version", limuVersion));// 调用的接口版本
        reqParam.add(new BasicNameValuePair("token", lt.getLimuToken()));
        reqParam.add(new BasicNameValuePair("bizType", lt.getBizType()));
        reqParam.add(new BasicNameValuePair("sign", LimuUtil.signConvert(LimuUtil.strSplitJoint(reqParam), limuApiSecret)));// 请求参数签名

        // 状态查询
        String jsonStr = httpClient.doPost(limuApiUrl, reqParam);

        // String code = getSelectCode(json);
        // super.logger.info("循环取的状态:" + code);
        super.logger.info("============================ userId:" + super.getUserId() + ",bizType:" + lt.getBizType() + ",循环取的信息:" + jsonStr + "============================");

        if (StringUtils.isBlank(jsonStr)) {
            // 未取到结果集
            return failure();
        }

        JSONObject json = JSONObject.parseObject(jsonStr);

        return success(json);
    }

    /**
     * 立木征信 提交请求（提交查询运营商的通信数据）
     *
     * @return
     * @throws IOException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    @RequestMapping("limuMobileApply")
    public Response limuMobileApply(@Validated LimuServicePassword lsp) throws JsonParseException, JsonMappingException, IOException {
        Long userId = super.getUserId();

        AuthProject apBaiqishi = authService.getAuthProject(userId, ConstUtil.BAIQISHI);
        if (apBaiqishi == null || apBaiqishi.getStatus() != 1){
            return failure("您的身份认证未通过");
        }

        AuthProject apBasicInfo = authService.getAuthProject(userId, ConstUtil.BASICINFO);
        if (apBasicInfo == null || apBasicInfo.getStatus() != 1){
            return failure("您的基本资料认证未通过");
        }

        AuthProject apContact = authService.getAuthProject(userId, ConstUtil.CONTACT);
        if (apContact == null || apContact.getStatus() != 1){
            return failure("您的人际关系认证未通过");
        }

        AuthProject apBank = authService.getAuthProject(userId, ConstUtil.BANK);
        if (apBank == null || apBank.getStatus() != 1){
            return failure("您的银行卡未绑定");
        }

        AuthProject apMobile = authService.getAuthProject(userId, ConstUtil.MOBILE);
        if (apMobile != null && apMobile.getStatus() == 1){
            return failure("您已经进行过运营商认证了");
        }

        User user = userService.selectById(userId);

        List<BasicNameValuePair> reqParam = new ArrayList<BasicNameValuePair>();
        reqParam.add(new BasicNameValuePair("method", "api.mobile.get"));// 接口名称
        reqParam.add(new BasicNameValuePair("username", user.getUsername()));// 账号,实则手机号码
        reqParam.add(new BasicNameValuePair("password", new String(Base64.encodeBase64(lsp.getServicePassword().getBytes("UTF-8")))));// 密码
        reqParam.add(new BasicNameValuePair("contentType", "all"));// 内容类型
        reqParam.add(new BasicNameValuePair("otherInfo", ""));// 其他信息

        super.logger.info("userId:" + userId + ", 立木征信 提交请求（查询运营商的通信数据）参数：" + JSON.toJSON(reqParam).toString());
        Object result = doPost(reqParam);
        super.logger.info("userId:" + userId + ", 立木征信 提交请求（查询运营商的通信数据）返回结果：" + result);

        if (result == null || result.equals("failure")){
            return failure("运营商认证失败，请稍后再试",result);
        }
        return success(result);
    }

    /**
     * Taobao（二维码登录）
     *
     * @return
     * @throws IOException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    @RequestMapping("limuTaobaoApplyByqr")
    public Response limuTaobaoApplyByqr() throws JsonParseException, JsonMappingException, IOException {
        Long userId = super.getUserId();
        AuthProject apBaiqishi = authService.getAuthProject(userId, ConstUtil.BAIQISHI);
        if (apBaiqishi == null || apBaiqishi.getStatus() != 1){
            return failure("您的身份认证未通过");
        }

        AuthProject apBasicInfo = authService.getAuthProject(userId, ConstUtil.BASICINFO);
        if (apBasicInfo == null || apBasicInfo.getStatus() != 1){
            return failure("您的基本资料认证未通过");
        }

        AuthProject apContact = authService.getAuthProject(userId, ConstUtil.CONTACT);
        if (apContact == null || apContact.getStatus() != 1){
            return failure("您的人际关系认证未通过");
        }

        AuthProject apBank = authService.getAuthProject(userId, ConstUtil.BANK);
        if (apBank == null || apBank.getStatus() != 1){
            return failure("您的银行卡未绑定");
        }

        AuthProject apMobile = authService.getAuthProject(userId, ConstUtil.MOBILE);
        if (apMobile != null || apMobile.getStatus() != 1){
            return failure("您的手机认证未通过");
        }

        AuthProject apTaobao = authService.getAuthProject(userId, ConstUtil.TAOBAO);
        if (apTaobao != null && apTaobao.getStatus() == 1){
            return failure("您已经进行过淘宝认证了");
        }
        List<BasicNameValuePair> reqParam = new ArrayList<BasicNameValuePair>();
        reqParam.add(new BasicNameValuePair("method", "api.taobao.get"));// 接口名称
        // reqParam.add(new BasicNameValuePair("username",
        // luap.getUsername()));// 账号,实则手机号码
        // reqParam.add(new BasicNameValuePair("password", new
        // String(Base64.encodeBase64(luap.getPassword().getBytes("UTF-8")))));//
        // 密码
        reqParam.add(new BasicNameValuePair("loginType", "qr"));//

        super.logger.info("userId:" + userId + ", 立木征信 提交请求（Taobao）参数：" + JSON.toJSON(reqParam).toString());
        Object result = doPost(reqParam);
        super.logger.info("userId:" + userId + ", 立木征信 提交请求（Taobao）返回结果：" + result);

        if (result == null || result.equals("failure")){
            return failure("淘宝认证失败，请稍后再试",result);
        }
        return success(result);
    }

    /**
     * 立木征信 查询结果并保存数据
     * @param ltab
     * @return
     * @throws Exception
     */

    @RequestMapping("limuGetResultAndSaveData")
    public Response limuGetAndSaveData(@Validated LimuTokenAndBizType ltab) throws Exception {
        Long userId = getUserId();

        String bizType = ltab.getBizType();
        AuthLimu authLimu = limuService.selectByUserId(userId, bizType);
        if (authLimu != null){
            return failure("认证失败，你已经做过此认证了");// 不为空时，表示已经查询过了。直接结束
        }

        AuthIdentity authIdentity = authService.getIdentity(userId);
        User user = userService.selectById(userId);

        List<BasicNameValuePair> reqParam = new ArrayList<BasicNameValuePair>();
        reqParam.add(new BasicNameValuePair("method", "api.common.getResult"));// 接口名称
        reqParam.add(new BasicNameValuePair("apiKey", limuApikey));// API授权
        reqParam.add(new BasicNameValuePair("version", limuVersion));// 调用的接口版本，可选值：1.0.0
        reqParam.add(new BasicNameValuePair("token", ltab.getLimuToken()));// 请求标识
        reqParam.add(new BasicNameValuePair("bizType", bizType));// 业务标识

        reqParam.add(new BasicNameValuePair("sign", LimuUtil.signConvert(LimuUtil.strSplitJoint(reqParam), limuApiSecret)));// 请求参数签名
        super.logger.info("userId:" + userId + ", 立木征信  " + bizType + " ,查询结果请求参数：" + JSON.toJSON(reqParam).toString());
        String jsonStr = httpClient.doPost(limuApiUrl, reqParam);
        super.logger.info("userId:" + userId + ", 立木征信  " + bizType + " ,查询结果集:" + jsonStr);

        String code = getSelectCode(jsonStr);
        if (!"0000".equals(code)) {
            super.logger.info("userId:" + userId + ", 立木征信 " + bizType + " 查询结果 code不等于'0000'");
            return failure();
        }

        JSONObject json = JSON.parseObject(jsonStr);
        DecimalFormat df = new DecimalFormat("######0"); //四色五入转换成整数

        String eventName = "";
        Integer eventType = 0;

        if (bizType.equals(ConstUtil.TAOBAO)) {
            String realName = null;
            String mobile = null;
            try{
                realName = json.getJSONObject("data").getJSONObject("basicInfo").getString("realName");
            }catch(ClassCastException e){
                logger.info("userId:"+userId+", 淘宝真实姓名为空");
            }

            try{
                mobile = json.getJSONObject("data").getJSONObject("basicInfo").getString("mobile");
            }catch(ClassCastException e){
                logger.info("userId:"+userId+", 淘宝手机号为空");
            }


            boolean realNameIsOK = realName != null && realName.equals(authIdentity.getName());

            // Taobao返回的电话号码是这样的格式的135****0691
            boolean mobileIsOk = mobile != null && mobile.equals(Util.mobileFormat(user.getUsername()));
            boolean realNameAndMobileIsBad = !(realNameIsOK || mobileIsOk);

            if (realNameAndMobileIsBad){
                logger.info("userId:"+userId+", 淘宝认证失败,非本人淘宝账号");
                return failure("认证失败，请使用您本人的淘宝帐号进行授权认证");
            }
        }

        if (bizType.equals(ConstUtil.MOBILE)) {

        }

        String dateTime = DateUtil.getCurrentDateTime();

        authLimu = new AuthLimu();
        authLimu.setContent(json.toJSONString());
        authLimu.setCreateTime(dateTime);
        authLimu.setId(super.getNextId());
        authLimu.setBizType(bizType);
        authLimu.setStatus(1);// 暂不使用，显示1
        authLimu.setUserId(userId);

        AuthProject ap = new AuthProject();
        ap.setId(super.getNextId());
        ap.setType(bizType);
        ap.setStatus(1);
        ap.setCreateTime(dateTime);
        ap.setUserId(userId);

       /* // 站内信
        UserMsg um = new UserMsg();
        um.setId(CodecUtil.createUUID());
        um.setCreateTime(dateTime);
        um.setContent(content);
        um.setStatus(1);
        um.setTitle("提额度通知");
        um.setType(4);// 类型 1消费，2还款，3逾期，4激活，5提额
        um.setUserId(userId);*/

        // 短信
        //smsContext.sendSms(la.getUsername(), content);

        limuService.limuGetResultAndSaveData(authLimu, ap);

        return success();

    }

    /**
     * @throws IOException
     * @throws JsonMappingException
     * @throws Exception
     * @Description:状态查询
     * @param @param token
     * @param @return
     * @throws
     */
    private static String getSelectCode(String json) throws Exception {

        if (StringUtils.isBlank(json)) {
            return "";
        }

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readValue(json, JsonNode.class);
        String code = rootNode.get("code").textValue();
        return code;
    }

}
